<?php
/**
 * Controlador del proceso de Login de usuarios.
 * 
 * @package Users
 * @author j.m.j.s. (25/07/2009)
 */
class LoginController extends CController
{
	/**
	 * @var unknown_type
	 */
	public $layout = 'login';

	/**
	 * Declares class-based actions.
	 */
	public function actions()
	{
		return array(
			// captcha action renders the CAPTCHA image
			// this is used by the contact page
			'captcha'=>array(
				'class'=>'CCaptchaAction',
				'backColor'=>0xF5F5F5,
				'foreColor'=>0x434C53,
				'width'=>148,
				'height'=>45,
				'padding'=>4,
			),
		);
	}

	/**
	 * @return array action filters
	 */
	public function filters()
	{
		return array(
			'accessControl', // perform access control for CRUD operations
		);
	}

	/**
	 * Specifies the access control rules.
	 * This method is used by the 'accessControl' filter.
	 *  
	 * @return array access control rules
 	 * @author j.m.j.s. (25/07/2009)
	 */
	public function accessRules()
	{
		return array(
			array('allow', //Solo usuarios logados
				'actions'=>array('logout','changePassword'),
				'users'=>array('@'),
			),
			array('allow', //Solo usuarios sin logar
				'actions'=>array('index','loginAjax','captcha','activate','newPassword','rememberPassword'),
				'users'=>array('*'),
			),
			array('deny',  // deny all users
				'users'=>array('*'),
			),
		);
	}
	
	/**
	 * Muestra el formulario de login
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 * @author j.m.j.s. (19/01/2010)
	 */
	public function actionIndex()
	{
		$session=new CHttpSession;
		$session->open();
		
  		// Se inicializa el contador de intentos de login
  		if(!isset($session['loginAttempts']))
  			$session['loginAttempts'] = 0;
		// Si la cantidad de intentos de login supera la cantidad permitida antes de bloquear la cuenta
		if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeLockUser'])
		{
			Yii::app()->user->setFlash('success',"Su cuenta de usuario fue inhabilitada por motivos de seguridad. Por favor contacte con el administrador del sistema para mas información.");
			$this->render('login',array('lockUser'=>true));
		}
		else
		{// Si todo está bien...
	  		$model=new UsersLoginForm;
	  		// collect user input data
			if(isset($_POST['UsersLoginForm']))
			{
				$model->attributes=$_POST['UsersLoginForm'];
				
		  		$model->scenario='formWithOutCapcha';//Por defecto se asume que no se muestra la imagen de seguridad capcha
		  		//Si la cantidad de intentos de login supera el limite entonces se valida el capcha
				if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeCapcha'])
					$model->scenario='formWithCapcha';
				
				$model->rijndaelKey = Yii::app()->params['rijndaelKey'];
				$model->cookieKey = Yii::app()->params['cookieKey'];
				
				// Valida los datos del usuario y redirecciona a la url indicada en la definicion del modulo
				if($model->validate())
				{
					unset($session['loginAttempts']);
					$this->redirect(Yii::app()->controller->module->params['logIn']);
				}
				else
				{
					$session['loginAttempts'] = $session['loginAttempts'] + 1;
					// Si la cantidad de intentos de login superó la cantidad de intentos permitidos, 
					// entonces se bloquea la cuenta del usuario ingresado si existe.
					if($session['loginAttempts'] == Yii::app()->params['attemptsBeforeLockUser'])
					{
						if($model = User::model()->findByAttributes(array('usr_nickname'=>$model->username)))
						{
							$model->usr_date_block = date('Y-m-d H:i:s');
							$model->usr_status = 0;
							$model->save();
							
							Yii::import('application.helpers.PHPMailer');
							$mail = new PHPMailer();
							$mail->IsHTML(true);
							$mail->Host = Yii::app()->controller->module->params['serverEmail'];
							$mail->From = Yii::app()->controller->module->params['supportEmail'];
							$mail->FromName = "Admin";
							$mail->Subject = utf8_decode('Activación de cuenta de usuario');	
							
					        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
					        // Se encripta la fecha de bloqueo y se agrega a la url de activación    
					        $cryptDate = $rijndael->linencrypthex($model->usr_date_block);
							$url = "http://{$_SERVER['HTTP_HOST']}/index.php?r=users/login/activate&c={$cryptDate}";
					        
					        $mail->Body = "Para activar de nuevo la cuenta de usuario debe hacer clic <a href='{$url}'>aquí</a>
										   o pegar en el navegador la siguiente url: {$url}";	
							
							$mail->AddAddress($model->usr_email);	
							$mail->Send();	
						}
						
					}
				}
			}
			else
			{
		  		$cookieNameUser = Yii::app()->params['cookieKey']."-qfdr4uc";
				//Si la cookie existe entonces se desencriptan los datos de usuario y contraseña y se muestran en el formulario.
				if(isset($_COOKIE[$cookieNameUser]))
				{
					$cookieNamePass = Yii::app()->params['cookieKey']."-qpdr3w";
					$rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
					$model->username = $rijndael->lindecrypthexComplex($_COOKIE[$cookieNameUser]);
			        $model->password = $rijndael->lindecrypthexComplex($_COOKIE[$cookieNamePass]);
			        $model->rememberMe = true;
				}
			}
			//Si la cantidad de intentos de login supera el limite entonces se muestra el capcha
			if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeCapcha'])
				$allowEmpty = false;
			else
				$allowEmpty = true;
			
			$this->render('login',array('model'=>$model, 'allowEmpty'=>$allowEmpty, 'lockUser'=>false));
		}
	}
	
	
		/**
	 * Muestra el formulario de login
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 * @author j.m.j.s. (19/01/2010)
	 */
	public function actionLoginAjax()
	{
		$session=new CHttpSession;
		$session->open();
		
  		// Se inicializa el contador de intentos de login
  		if(!isset($session['loginAttempts']))
  			$session['loginAttempts'] = 0;
		// Si la cantidad de intentos de login supera la cantidad permitida antes de bloquear la cuenta
		if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeLockUser'])
		{
				echo json_encode(array('username'=>'','password'=>'','error'=>"Su cuenta de usuario fue inhabilitada por motivos de seguridad. Por favor contacte con el administrador del sistema para mas información."));
			
			Yii::app()->end();
		}
		else
		{// Si todo está bien...
	  		$model=new UsersLoginForm;
	  		// collect user input data
			if(isset($_POST['UsersLoginForm']))
			{
				
        $model->attributes=$_POST['UsersLoginForm'];
				
		  		$model->scenario='formWithOutCapcha';//Por defecto se asume que no se muestra la imagen de seguridad capcha
		  		//Si la cantidad de intentos de login supera el limite entonces se valida el capcha
				if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeCapcha'])
					$model->scenario='formWithCapcha';
				
				$model->rijndaelKey = Yii::app()->params['rijndaelKey'];
				$model->cookieKey = Yii::app()->params['cookieKey'];
				
				// Valida los datos del usuario y redirecciona a la url indicada en la definicion del modulo
				if($model->validate())
				{
					
          unset($session['loginAttempts']);
          print_r(json_encode(array('url'=>Yii::app()->controller->module->params['logIn'])));
          Yii::app()->end();
					
				}
				else
				{
				  
					$session['loginAttempts'] = $session['loginAttempts'] + 1;
					// Si la cantidad de intentos de login superó la cantidad de intentos permitidos, 
					// entonces se bloquea la cuenta del usuario ingresado si existe.
					if($session['loginAttempts'] == Yii::app()->params['attemptsBeforeLockUser'])
					{
						if($model = User::model()->findByAttributes(array('usr_nickname'=>$model->username)))
						{
							$model->usr_date_block = date('Y-m-d H:i:s');
							$model->usr_status = 0;
							$model->save();
							
							Yii::import('application.helpers.PHPMailer');
							$mail = new PHPMailer();
							$mail->IsHTML(true);
							$mail->Host = Yii::app()->controller->module->params['serverEmail'];
							$mail->From = Yii::app()->controller->module->params['supportEmail'];
							$mail->FromName = "Admin";
							$mail->Subject = utf8_decode('Activación de cuenta de usuario');	
							
					        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
					        // Se encripta la fecha de bloqueo y se agrega a la url de activación    
					        $cryptDate = $rijndael->linencrypthex($model->usr_date_block);
							$url = "http://{$_SERVER['HTTP_HOST']}/index.php?r=users/login/activate&c={$cryptDate}";
					        
					        $mail->Body = "Para activar de nuevo la cuenta de usuario debe hacer clic <a href='{$url}'>aquí</a>
										   o pegar en el navegador la siguiente url: {$url}";	
							
							$mail->AddAddress($model->usr_email);	
							$mail->Send();	
						}
						
					}
				}
			}
			else
			{
		  		$cookieNameUser = Yii::app()->params['cookieKey']."-qfdr4uc";
				//Si la cookie existe entonces se desencriptan los datos de usuario y contraseña y se muestran en el formulario.
				if(isset($_COOKIE[$cookieNameUser]))
				{
					$cookieNamePass = Yii::app()->params['cookieKey']."-qpdr3w";
					$rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
					$model->username = $rijndael->lindecrypthexComplex($_COOKIE[$cookieNameUser]);
			        $model->password = $rijndael->lindecrypthexComplex($_COOKIE[$cookieNamePass]);
			        $model->rememberMe = true;
				}
			}
			//Si la cantidad de intentos de login supera el limite entonces se muestra el capcha
			if($session['loginAttempts'] >= Yii::app()->params['attemptsBeforeCapcha'])
				$allowEmpty = false;
			else
				$allowEmpty = true;
			
		  print_r (json_encode($model->getErrors()));
      Yii::app()->end();

		}
	}

	/**
	 * Cierra la sesión y muestra el fomulario de login
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	public function actionLogout()
	{
		$session=new CHttpSession;
		$session->open();
		$session->destroy();
		
		Yii::app()->user->logout(false);
		$this->redirect(Yii::app()->controller->module->params['logOut']);
	}

	/**
	 * Permite activar de nuevo la cuenta de usuario con el enlace enviado al correo
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	public function actionActivate()
	{
		if(isset($_GET['c']) and $_GET['c'] != '')
		{
	        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
	        // Se desencripta el valor para verificar que corresponda con la fecha de bloqueo    
	        $decryptDate = $rijndael->lindecrypthex($_GET['c']);
	        
	        if($model = User::model()->findByAttributes(array('usr_date_block'=>$decryptDate)))
	        {
	        	$model->usr_status = 1;
	        	$model->usr_date_block = '';
	        	$model->save();
	        	
				$session=new CHttpSession;
				$session->open();
				$session->destroy();
	        }
		}
	        
        $this->redirect(array('index'));
	}
	/**
	 * Muestra un formulario en el que se puede cambiar la contraseña por otra
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	public function actionChangePassword()
	{
		$model = User::model()->findbyPk(Yii::app()->user->id);
		
		if(isset($_POST['passwordPwd']))
		{
			if($_POST['passwordPwd'] == '')
			{
				Yii::app()->user->setFlash('error',"El campo de Contraseña actual no puede ser vacio.");
			}
			if($_POST['passwordPwdNew'] == '')
			{
				Yii::app()->user->setFlash('error',"El campo de Contraseña nueva no puede ser vacio.");
			}
			else if($_POST['passwordPwdNew'] != $_POST['passwordPwdNew2'])
			{
				Yii::app()->user->setFlash('error',"El campo de Contraseña nueva y Repetir contraseña no pueden ser diferentes.");
			}
			else
			{
		        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
		        // Se desencripta la contraseña para compararla con la que colocó el usuario en el formulario.
		        $currentPassword = $rijndael->lindecrypthexComplex($model->usr_password);
		        //Si el usuario ingresó correctamente el password actual...
		        if($_POST['passwordPwd'] == $currentPassword)
		        {
		        	$model->usr_password = $rijndael->linencrypthexComplex($_POST['passwordPwdNew'],$model->usr_nickname);
		        	// Si el usuario cambió el email entonces se actualiza tambien
		        	if($_POST['User']['usr_email'] != $model->usr_email)
		        		$model->usr_email = $_POST['User']['usr_email'];
		        	
		        	$model->save();
					
		        	Yii::app()->user->setFlash('success',"La contraseña se ha actualizado correctamente.");
		        }
		        else
					Yii::app()->user->setFlash('error',"La contraseña actual no es correcta.");
			}			
		}
		$this->layout = 'application.views.layouts.administrator';
		$this->render('changePassword',array('model'=>$model));
	}

	/**
	 * Permite crear una contraseña nueva, es especialmente util cuando vamos a crear nuestro primer usuario.
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	public function actionNewPassword()
	{
		if(isset($_GET['usr']) and isset($_GET['pass']))
		{
	        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
	        // Se  encripta la contraseña
	        $passCrypt = $rijndael->linencrypthexComplex($_GET['pass'],$_GET['usr']);

			echo utf8_decode('<b>usuario: </b>'.$_GET['usr'].'<br>');
			echo utf8_decode('<b>contraseña </b>:<input type="text" value="'.$passCrypt.'" size=40>');
		}
		else
		{
	        echo utf8_decode('Por favor en la url agregue una variable <b>"usr"</b> para el nombre de usuario y una variable <b>"pass"</b> para la nueva contraseña.<br>');
			echo utf8_decode('La url quedaria por ejemplo: <b>index.php?r=users/login/newPassword&usr=root&pass=troya</b>');
		}
	}
	
	/**
	 * Muestra el formulario de recordar contraseña y permite enviar un email con el recordatorio de la clave.
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	public function actionRememberPassword()
	{
		$model = User::model();
		$model->scenario='rememberPassword';
		$errors = false;
		$success = false;
		
  		if(isset($_POST['User']))
		{
			$model->attributes=$_POST['User'];
			if($model->validate())
			{
				$user = User::model()->findByAttributes(array('usr_email'=>$model->usr_email));
				
				Yii::import('application.helpers.PHPMailer');
				$mail = new PHPMailer();
				$mail->IsHTML(true);
				$mail->Host = Yii::app()->controller->module->params['serverEmail'];
				$mail->From = Yii::app()->controller->module->params['supportEmail'];
				$mail->FromName = "Admin";
				$mail->Subject = utf8_decode('Recordatorio de clave');	

		        $this->createTempImage($user->usr_password);
				
				$mail->AddEmbeddedImage('assets/users_fgsd43.jpg', 'password');
				
		        $mail->Body = 'Su clave es: <img src="cid:password" />';	
				
				$mail->AddAddress($user->usr_email);	
				$mail->Send();
				
				$this->destroyTempImage();

				$success = '-Si ha enviado a su email un correo con la clave.';
			}
			else
				$errors = PXFunctions::array2text($model->getErrors());
		
		}
		$this->layout = false;
		$this->render('rememberPassword',array('model'=>$model,'errors'=>$errors,'success'=>$success));
	}
	
	/**
	 * Crea una imagen temporal con un texto pasado por parametro.
	 * 
	 * @param $text - El texto que aparecerá en la imagen.
	 * @author j.m.j.s. (25/07/2009)
	 */
	private function createTempImage($text)
	{
        $rijndael = new RijndaelHex(Yii::app()->params['rijndaelKey']);
        $text = $rijndael->lindecrypthexComplex($text);

		$im = imagecreate(100, 30);
		imagecolorallocate($im, 255, 255, 255);
		imagestring($im, 3, 5, 5,  $text, 1);
		imagejpeg($im,'assets/users_fgsd43.jpg');
		imagedestroy($im);
	}

	/**
	 * Elimina la imagen temporal.
	 * 
	 * @author j.m.j.s. (25/07/2009)
	 */
	private function destroyTempImage()
	{
		if(file_exists('assets/users_fgsd43.jpg'))
			unlink('assets/users_fgsd43.jpg');		
	}
}